package com.lxw.station.service;

import com.lxw.station.dto.HmacSHA256Dto;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URL;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class HmacSHA256Util {

    @SneakyThrows
    public static String hmacSHA256(String secret, String message) {
        Mac hmacSha256 = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
        hmacSha256.init(secret_key);
        byte[] bytes = hmacSha256.doFinal(message.getBytes());
        return Base64.getEncoder().encodeToString(bytes);
    }

    /**
     * 构建需要加密的字符串
     */
    @SneakyThrows
    private static String getMessage(HmacSHA256Dto hmacSHA256Dto) {
        URL url = new URL(hmacSHA256Dto.getUrl());
        // 处理get请求的查询参数,例如 id=136507441&model_type=
        String query = url.getQuery();
        if (StringUtils.hasText(query)) {
            // 例如 id=136507441
            String[] split = query.split("&");
            for (String s : split) {
                String[] kv = s.split("=");
                if (kv.length == 2) {
                    hmacSHA256Dto.getParams().put(kv[0], kv[1]);
                } else {
                    hmacSHA256Dto.getParams().put(kv[0], "");
                }
            }
        }
        String path = url.getPath();
        StringBuffer sb = new StringBuffer();
        String contentType = hmacSHA256Dto.getContentType();
        sb.append(hmacSHA256Dto.getMethod() + "\n")
                .append(hmacSHA256Dto.getAccept() + "\n\n");
        if (StringUtils.hasText(contentType)) {
            if (contentType.endsWith(";")) {
                sb.append(contentType);
            }else {
                sb.append(contentType).append(";");
            }
        }
        sb.append("\n")
                .append(hmacSHA256Dto.getDate() + "\n")
                .append("x-ca-key:" + hmacSHA256Dto.getXCaKey() + "\n")
                .append("x-ca-nonce:").append(hmacSHA256Dto.getXCaNonce() + "\n")
                .append(path);
        Map<String, Object> params = hmacSHA256Dto.getParams();
        if (!CollectionUtils.isEmpty(params)) {
            List<String> keys = new ArrayList<>(params.keySet());
            Collections.sort(keys);
            for (int i = 0; i < keys.size(); i++) {
                String value = keys.get(i);
                if (StringUtils.hasText(value)) {
                    if (i == 0) {
                        sb.append("?").append(value).append("=").append(params.get(value));
                    } else {
                        sb.append("&").append(value).append("=").append(params.get(value));
                    }
                }
            }
        }
        if (sb.lastIndexOf("=") == sb.length() - 1) {
            sb.deleteCharAt(sb.lastIndexOf("="));
        }
        return sb.toString();
    }

    /**
     * 获取签名
     */
    public static String getXCaSignature(HmacSHA256Dto hmacSHA256Dto) {
        String message = getMessage(hmacSHA256Dto);
        log.info(message.replace("\n", "|"));
        return hmacSHA256(hmacSHA256Dto.getAppSecret(), message);

    }

    public static void main(String[] args) {
        // aFS1DrHT/meXJ/9ookJkb6RXJcgK2jawwlBxMRCLuPU=
        getTest1();
//        getTest2();
    }

    /**
     * get请求无空参数
     */
//    private static void getTest1() {
//        HmacSHA256Dto hmacSHA256Dto = new HmacSHA256Dto();
//        hmacSHA256Dto.setMethod("GET").setAccept("application/json, text/plain, */*")
//                .setContentType("")
//                .setXCaNonce("dbe94670-17cf-4103-806b-bdb647be45f3")
//                .setUrl("https://bizapi.csdn.net/blog/phoenix/console/v1/article/list?page=2&pageSize=20");
//        Map<String, Object> param = new HashMap<>();
//        param.put("page", 2);
//        param.put("pageSize", 20);
//        hmacSHA256Dto.setParams(param);
//        String xCaSignature = getXCaSignature(hmacSHA256Dto);
//        System.out.println("x-ca-signature:" + xCaSignature);
//    }
    private static void getTest1() {
        HmacSHA256Dto hmacSHA256Dto = new HmacSHA256Dto();
        hmacSHA256Dto.setMethod("GET").setAccept("application/json, text/plain, */*")
                .setContentType("")
                .setXCaNonce("d6b123d3-8d07-48b1-b6c2-6dab3484960a")
                .setUrl("https://bizapi.csdn.net/download-console-api/v1/user/checkUploadSource?fileMd5=90355637d21400567cd1fafdab9784bb&fileType=md");
        Map<String, Object> param = new HashMap<>();
        param.put("fileMd5", "90355637d21400567cd1fafdab9784bb");
        param.put("fileType", "md");
        hmacSHA256Dto.setParams(param);
        String xCaSignature = getXCaSignature(hmacSHA256Dto);
        System.out.println("x-ca-signature:" + xCaSignature);
    }

    /**
     * get请求有空参数
     */
    private static void getTest2() {
        HmacSHA256Dto hmacSHA256Dto = new HmacSHA256Dto();
        hmacSHA256Dto.setMethod("GET").setAccept("*/*")
                .setXCaNonce("c7e725b6-135e-4cbf-b7b1-f4e49f633e88")
                .setUrl("https://bizapi.csdn.net/blog-console-api/v3/editor/getArticle?id=137974733&model_type=");
        String xCaSignature = getXCaSignature(hmacSHA256Dto);
        System.out.println("x-ca-signature:" + xCaSignature);
    }

    /**
     * post请求测试
     */
    private static void postTest() {
        HmacSHA256Dto hmacSHA256Dto = new HmacSHA256Dto();
        hmacSHA256Dto.setMethod("POST").setAccept("*/*")
                .setContentType("application/json;")
                .setXCaNonce("04db9c7c-b281-4117-944a-98c86d9f27a2")
                .setUrl("https://bizapi.csdn.net/blog-console-api/v3/mdeditor/saveArticle");
        String xCaSignature = getXCaSignature(hmacSHA256Dto);
        System.out.println("x-ca-signature:" + xCaSignature);
    }

}


